
PM_FUNC_PUBLIC_ATTRIB EventRoundStart()
{
	pokemod_funcstart_debug( "EventRoundStart" );

	g_iRoundState &= ~ROUND_FREEZETIME;

	pokemod_funcend_debug( "EventRoundStart" );
}

PM_FUNC_PUBLIC_ATTRIB EventHLTV()
{
	pokemod_funcstart_debug( "EventHLTV" );

	new Int:iEnt = -1;
	while ( ( iEnt = fm_find_ent_by_class( iEnt, szEntityPokeMod ) ) )
		EntityKill( iEnt );

	iEnt = -1;
	while ( ( iEnt = fm_find_ent_by_class( iEnt, szEntityPokeSkill ) ) )
	{
		EntitySoundStop( iEnt );
		EntityKill( iEnt );
	}

	EntityOak( 1 );
	EntityOak( 2 );

	g_iRoundState |= ROUND_FREEZETIME;
	g_iRoundState &= ~ROUND_ENDED;

	pokemod_funcend_debug( "EventHLTV" );
}

PM_FUNC_PUBLIC_ATTRIB EventRespawnPost( Int:id )
{
	if ( g_iState == PM_DISABLED )
		return HAM_IGNORED;

	if ( !is_user_alive( id ) )
		return HAM_IGNORED;

	pokemod_funcstart_debug( "EventRespawnPost" );

	if ( !PlayerGetInfo( id, PINFO_VERSION ) )
	{
		SetupPlayer( id );
	}

	if ( PlayerGetInfo( id, PINFO_BOT ) )
	{
		PlayerSetInfo( id, PINFO_BOT_ACTIONS, MENU_BOT_ACTIONS );
		MenuMain( id, .bForceDisplay = false );
	}

	new Int:iPokeNum = PlayerGetInfo( id, PINFO_ACTIVE_POKENUM );
	if ( g_iPlayerPokemonStats[ id ][ iPokeNum ][ POKESTAT_HP ] <= 0 )
	{
		PokemonFainted( id, iPokeNum );
	}

	PlayerAddInfo( id, PINFO_TRAINING_BOOST, SettingGetNum( TRAINING_SPAWN_BOOST ) );

	PlayerLoadStats( id, iPokeNum, .setHP = true );

	for ( new PM_STATUS:iStatNum; iStatNum < PM_STATUS; iStatNum++ )
	{
		g_iPlayerStatus[ id ][ iStatNum ][ STATUS_AMOUNT ] = 0;
	}

	SkillSetDelay( id, 0.0 );

	PlayerSetInfo( id, PINFO_STATUS_EFFECT, 0 );

	SkillCallType( CALL_SPAWN, id );

	SkillAddDelay( id, SettingGetFloat( SPAWN_DELAY ) );

	UnStuck( id );

	new Int:iPlayers = get_playersnum();
	new Int:iItemCount = max( 2, iPlayers / 2 );
	while ( iItemCount > ItemEntityCount() )
	{
		ItemEntityCreate();
	}

	pokemod_funcend_debug( "EventRespawnPost" );

	return HAM_IGNORED;
}

PM_FUNC_PUBLIC_ATTRIB EventCurWeapon( Int:id )
{
	if ( g_iState == PM_DISABLED || g_iRoundState & ROUND_FREEZETIME )
		return;

	pokemod_funcstart_debug( "EventCurWeapon" );

	new Float:fWeaponSpeed;
	switch( get_user_weapon( id ) )
	{
		case	CSW_P228, CSW_HEGRENADE, CSW_C4, CSW_MAC10, CSW_SMOKEGRENADE,
				CSW_ELITE, CSW_FIVESEVEN, CSW_UMP45, CSW_USP, CSW_GLOCK18, CSW_MP5NAVY,
				CSW_TMP, CSW_FLASHBANG, CSW_DEAGLE, CSW_KNIFE: fWeaponSpeed = 250.0;
		case	CSW_SCOUT: fWeaponSpeed = 260.0;
		case	CSW_XM1014, CSW_AUG, CSW_GALI, CSW_FAMAS: fWeaponSpeed = 240.0;
		case	CSW_SG550, CSW_AWP, CSW_G3SG1: fWeaponSpeed = 210.0;
		case	CSW_M249: fWeaponSpeed = 220.0;
		case	CSW_M3, CSW_M4A1: fWeaponSpeed = 230.0;
		case	CSW_SG552: fWeaponSpeed = 235.0;
		case	CSW_AK47: fWeaponSpeed = 221.0;
		case	CSW_P90: fWeaponSpeed = 245.0;

		default: fWeaponSpeed = 240.0;
	}

	if ( g_iPlayerStatus[ id ][ STATUS_ASLEEP ][ STATUS_AMOUNT ] > 0 || g_iPlayerStatus[ id ][ STATUS_PARALYZE ][ STATUS_AMOUNT ] > 0 )
	{
		fWeaponSpeed = 1.0;
	}
	else if ( g_iPlayerStatus[ id ][ STATUS_SLOW ][ STATUS_AMOUNT ] > 0 || g_iPlayerStatus[ id ][ STATUS_FROZEN ][ STATUS_AMOUNT ] > 0 )
	{
		fWeaponSpeed *= 0.25;
	}

	CoreCallValues( .fSpeed = fWeaponSpeed );

	SkillCallType( CALL_SPEED_UPDATE, id );

	fWeaponSpeed = g_fSpeed;

	CoreCallRestoreValues();

	set_user_maxspeed( id, fWeaponSpeed );

	pokemod_funcend_debug( "EventCurWeapon" );
}

PM_FUNC_PUBLIC_ATTRIB EventDamage( Int:iVictim, Int:weaponEnt, Int:iAttacker, Float:fDamage, Int:iDamageBits )
{
	if ( g_iState == PM_DISABLED )
		return HAM_IGNORED;

	pokemod_funcstart_debug( "EventDamage" );

	if ( is_user_alive( iAttacker ) && cs_get_user_team( iVictim ) == cs_get_user_team( iAttacker ) && !get_pcvar_num( mp_friendlyfire ) )
	{
		pokemod_funcend_debug( "EventDamage TeamAttack (FF off)" );
		return HAM_IGNORED;
	}

	if ( !iAttacker )
	{
		pokemod_funcend_debug( "EventDamage No Attacker" );
		return HAM_IGNORED;
	}

	new iHitZone = get_pdata_int( iVictim, m_LastHitGroup, ._linuxdiff = 5 );

	new iWeaponID;
	if ( weaponEnt == iAttacker && PlayerGetInfo( iAttacker, PINFO_CONNECT ) )
	{
		iWeaponID = get_user_weapon( iAttacker );
	}
	else
	{
		if ( EntityValid( weaponEnt ) )
		{
			new String:szClassname[ 32 ];
			pev( weaponEnt, pev_classname, szClassname, charsmax(szClassname) );
			if ( equal( szClassname, "grenade" ) )
			{
				if ( get_pdata_int( weaponEnt, 96 ) & ( 1 << 8 ) )
				{
					iWeaponID = CSW_C4;
				}
				else
				{
					new bits = get_pdata_int( weaponEnt, 114 );
					if ( bits & ( 1 << 0 ) )
						iWeaponID = CSW_HEGRENADE;
					else if ( bits & ( 1 << 1 ) )
						iWeaponID = CSW_SMOKEGRENADE;
					else if ( !bits )
						iWeaponID = CSW_FLASHBANG;
				}
			}
		}
	}

	CoreCallValues( .iVictim = iVictim,
					.iAttacker = iAttacker,
					.fDamage = fDamage,
					.iDamageBits = iDamageBits,
					.iHitZone = iHitZone,
					.iWeaponID = iWeaponID
					);

	SkillCallType( CALL_TAKE_DAMAGE, iVictim );
	SkillCallType( CALL_GIVE_DAMAGE, iAttacker );

	if ( g_iVictim != iVictim )
		SetHamParamEntity( 1, ( iVictim = g_iVictim ) );
	if ( g_iAttacker != iAttacker )
		SetHamParamEntity( 3, ( iAttacker = g_iAttacker ) );
	if ( g_fDamage != fDamage )
		SetHamParamFloat( 4, ( fDamage = g_fDamage ) );
	if ( g_iDamageBits != iDamageBits )
		SetHamParamInteger( 5, ( iDamageBits = g_iDamageBits ) );

	CoreCallRestoreValues();

	if ( fDamage > 0.0 )
	{
		PokemonGiveDamage( iAttacker );
		PokemonTakeDamage( iVictim, PlayerGetInfo( iVictim, PINFO_ACTIVE_POKENUM ), floatround( fDamage ) );

		//wake them up if they were sleeping
		if ( g_iPlayerStatus[ iVictim ][ STATUS_ASLEEP ][ STATUS_AMOUNT ] > 0 && SettingGetNum( DAMAGE_AWAKEN ) )
			g_iPlayerStatus[ iVictim ][ STATUS_ASLEEP ][ STATUS_AMOUNT ] = 0;
	}

	pokemod_funcend_debug( "EventDamage" );

	return HAM_IGNORED;
}

PM_FUNC_PUBLIC_ATTRIB EventKilled( Int:iVictim, Int:iKiller )
{
	if ( g_iState == PM_DISABLED )
		return HAM_IGNORED;

	pokemod_funcstart_debug( "EventKilled" );

	CoreCallValues( .iVictim = iVictim, .iAttacker = iKiller );

	SkillCallType( CALL_DEATH, iVictim );

	if ( g_iVictim != iVictim )
		SetHamParamEntity( 1, ( iVictim = g_iVictim ) );
	if ( g_iAttacker != iKiller )
		SetHamParamEntity( 2, ( iKiller = g_iAttacker ) );

	if ( PlayerGetInfo( iVictim, PINFO_CONNECT ) )
		PlayerAddInfo( iVictim, PINFO_TRAINING_BOOST, SettingGetNum( TRAINING_DEATH_BOOST ) );

	if ( PlayerGetInfo( iKiller, PINFO_CONNECT ) )
		PlayerAddInfo( iKiller, PINFO_TRAINING_BOOST, SettingGetNum( TRAINING_KILL_BOOST ) );

	LocationScript( .iPlayer = iVictim, .iLocation = PlayerGetInfo( iVictim, PINFO_LOCATION ), .szForward = "Death" );
	LocationScript( .iPlayer = iKiller, .iLocation = PlayerGetInfo( iKiller, PINFO_LOCATION ), .szForward = "Kill" );

	CoreCallRestoreValues();

	pokemod_funcend_debug( "EventKilled" );

	return HAM_IGNORED;
}

PM_FUNC_PUBLIC_ATTRIB EventRoundEnd()
{
	pokemod_funcstart_debug( "EventRoundEnd" );

	new Int:iEnt = -1;
	while ( ( iEnt = fm_find_ent_by_class( iEnt, szEntityPokeMod ) ) )
		EntityKill( iEnt );
	iEnt = -1;
	while ( ( iEnt = fm_find_ent_by_class( iEnt, szEntityPokeOak ) ) )
		EntityKill( iEnt );
	iEnt = -1;
	while ( ( iEnt = fm_find_ent_by_class( iEnt, szEntityPokeSkill ) ) )
	{
		EntitySoundStop( iEnt );
		EntityKill( iEnt );
	}

	if ( g_iState == PM_DISABLED )
	{
		pokemod_funcend_debug( "EventRoundEnd Disabled" );
		return;
	}

	g_iRoundState |= ROUND_ENDED;

	new Int:iEncounterPoke, Int:iSkillNum;
	LoopThroughPlayersFlags( iPlayer, PLAYER_FLAGS_NOHLTV )
	{
		SkillCallType( CALL_ROUND_END, iPlayer );

		for ( iSkillNum = 0; iSkillNum < SKILLS_PER_POKEMON; iSkillNum++ )
		{
			remove_task( TASK_POKESKILL_CUSTOM + ( iPlayer * SKILLS_PER_POKEMON ) + iSkillNum );
		}

		iEncounterPoke = PlayerGetInfo( iPlayer, PINFO_ENCOUNTER_POKEMON );
		if ( iEncounterPoke > 0 )
		{
			PokemonGiveDamage( iPlayer );
		}

		else if ( is_user_alive( iPlayer ) && PlayerGetInfo( iPlayer, PINFO_TRAVELING ) )
		{
			LocationUpdate( iPlayer );
		}
	}

	pokemod_funcend_debug( "EventRoundEnd" );
}

PM_FUNC_PUBLIC_ATTRIB EventLoop( Int:iLoopEntity )
{
	if ( g_iEntityLoop != iLoopEntity )
		return;

	set_pev( iLoopEntity, pev_nextthink, get_gametime() + 1.0 );

	if ( g_iState == PM_DISABLED )
		return;

	pokemod_funcstart_debug( "EventLoop" );

	new bool:bTraveling;

	LoopThroughPlayersFlags( iPlayer, PLAYER_FLAGS_ALL )
	{
		if ( is_user_alive( iPlayer ) )
		{
			if ( PlayerGetInfo( iPlayer, PINFO_ENCOUNTER_POKEMON ) <= 0 )
			{
				bTraveling = bool:PlayerGetInfo( iPlayer, PINFO_TRAVELING );
				if ( Chance( bTraveling ? ENCOUNTER_CHANCE : ENCOUNTER_CHANCE_TRAVELING ) )
				{
					ArrayClear( g_iScriptEncounters );

					LocationScript( iPlayer, PlayerGetInfo( iPlayer, PINFO_LOCATION ), "Traveling", "" );

					EncounterFight( iPlayer );
				}
				else if ( bTraveling )
				{
					new Int:iTravelTime = PlayerGetInfo( iPlayer, PINFO_TRAVEL_TIME ) - 1;

					if ( iTravelTime <= 0 )
						LocationUpdate( iPlayer );
					else
						PlayerSetInfo( iPlayer, PINFO_TRAVEL_TIME, iTravelTime );
				}
			}

			SkillCallType( CALL_EVERY_SECOND, iPlayer );

			PlayerHUD( iPlayer, iPlayer );
		}
		else
		{
			PlayerHUD( iPlayer, pev( iPlayer, pev_iuser2 ) );
		}
	}

	pokemod_funcend_debug( "EventLoop" );
}

PM_FUNC_PUBLIC_ATTRIB EventStatusValue( Int:iPlayer )
{
	if ( g_iState == PM_DISABLED || !is_user_alive( iPlayer ) )
		return;

	pokemod_funcstart_debug( "EventStatusValue" );

	new Int:iAimEnt = read_data( 2 );
	if ( is_user_alive( iAimEnt ) )
	{
		CoreCallValues( .iVictim = iAimEnt );

		SkillCallType( CALL_AIM_AT_PLAYER, iPlayer );

		CoreCallRestoreValues();
	}

	pokemod_funcend_debug( "EventStatusValue" );
}

PM_FUNC_PUBLIC_ATTRIB EventTouch( Int:iToucher, Int:iTouched )
{
	if ( g_iState == PM_DISABLED )
		return;

	if ( !is_user_alive( iToucher ) )
		return;

	if ( EntityValid( iTouched ) )
	{
		new String:szClass[32];
		pev( iTouched, pev_classname, szClass, charsmax(szClass) );

		pokemod_funcstart_debug( "EventTouch %s", szClass );

		if ( equal( szClass, szEntityPokeOak ) )
		{
			new Float:fDist = entity_range( iToucher, iTouched );
			if ( fDist > 32.0 )
			{
				new Vector:vVelocity[3];
				EntityGetVelocity( iToucher, vVelocity );
				vVelocity[0] *= 1.5;
				vVelocity[1] *= 1.5;
				EntitySetVelocity( iTouched, vVelocity );

				new Float:fGameTime = get_gametime();
				new Float:fLastUse;
				pev( iTouched, pev_starttime, fLastUse );
				if ( fLastUse + 1.0 < fGameTime )
				{
					set_pev( iTouched, pev_starttime, fGameTime );
					MenuMain( iToucher, .bForceDisplay = true );
				}
			}
			else
			{
				UnStuck( iToucher );
			}
		}
		else if ( equal( szClass, szEntityPokeItem ) )
		{
			g_iScriptItemsGiven = 0;

			new Int:iEncounterPoke = PlayerGetInfo( iToucher, PINFO_ENCOUNTER_POKEMON );

			LocationScript( iToucher, PlayerGetInfo( iToucher, PINFO_LOCATION ), "BallPickup", "" );

			//Check to make sure no items were given and they didn't start fighting a pokemon
			if ( !g_iScriptItemsGiven && iEncounterPoke == PlayerGetInfo( iToucher, PINFO_ENCOUNTER_POKEMON ) )
			{
				new String:szRandomStuff[][] = {
					"rock",
					"leaf",
					"stone",
					"tree",
					"turd",
					"bush",
					"shoe"
				}
				DHudEventMessage( iToucher, "That wasn't a pokeball, it was a %s!", szRandomStuff[ random( sizeof szRandomStuff ) ] );
			}

			EntityKill( iTouched );
		}
		else
		{
			new POKESKILL:iSkillID = POKESKILL:PlayerGetInfo( iToucher, PINFO_BOOST_SKILL );
			new Int:iBoostDamage = PlayerGetInfo( iToucher, PINFO_BOOST_DAMAGE );

			CoreCallValues( .iVictim = iTouched, .fDamage = float( iBoostDamage ) );

			if ( iSkillID != SKILL_INVALID )
			{
				if ( iBoostDamage )
				{
					g_iSkillID = iSkillID;
					SkillDamage( .victim = iTouched,
								.attacker = iToucher,
								.damage = iBoostDamage
								);
					g_iSkillID = SKILL_INVALID;
				}

				if ( SKILL_CALL:SkillInfo( iSkillID, SI_CALLTYPE ) & CALL_BOOST_HIT )
				{
					new Int:iSkillNum = PlayerGetInfo( iToucher, PINFO_BOOST_SKILLNUM );
					SkillCall( .skillID = iSkillID,
								.call = CALL_BOOST_HIT,
								.iPlayer = iToucher,
								.skillNum = iSkillNum,
								.addDelayTime = true
							);
				}
			}

			SkillCallType( CALL_PLAYER_TOUCH, iToucher );

			CoreCallRestoreValues();
		}
	}
	else
	{
		pokemod_funcstart_debug( "EventTouch World" );

		new POKESKILL:iSkillID = POKESKILL:PlayerGetInfo( iToucher, PINFO_BOOST_SKILL );
		if ( iSkillID != SKILL_INVALID )
		{
			if ( SKILL_CALL:SkillInfo( iSkillID, SI_CALLTYPE ) & CALL_BOOST_HIT )
			{
				new Int:iSkillNum = PlayerGetInfo( iToucher, PINFO_BOOST_SKILLNUM );
				SkillCall( .skillID = iSkillID,
							.call = CALL_BOOST_HIT,
							.iPlayer = iToucher,
							.skillNum = iSkillNum,
							.addDelayTime = true
						);
			}

			PlayerSetInfo( iToucher, PINFO_BOOST_SKILL, SKILL_INVALID );
			PlayerSetInfo( iToucher, PINFO_BOOST_DAMAGE, 0 );
		}
	}

	pokemod_funcend_debug( "EventTouch" );
}


PM_FUNC_PUBLIC_ATTRIB EventSkillTouch( Int:iToucher, Int:iTouched )
{
	if ( !EntityValid( iToucher ) )
		return;

	if ( g_iState == PM_DISABLED )
	{
		EntitySoundStop( iToucher );
		EntityKill( iToucher );
		return;
	}

	new Int:iOwner = EntityGetNum( iToucher, ENTITY_OWNER );
	if ( iOwner == iTouched || iOwner == pev( iTouched, pev_owner ) )
		return;

	if ( !is_user_connected( iOwner ) )
	{
		EntitySoundStop( iToucher );
		EntityKill( iToucher );
		return;
	}

	new SKILLENT_PROP:iProp = SKILLENT_PROP:EntityGetNum( iToucher, ENTITY_PROPERTIES );
	new POKESKILL:skillID = POKESKILL:EntityGetNum( iToucher, ENTITY_SKILL );

	if ( !( iProp & SEP_TOUCH ) )
		return;

	pokemod_funcstart_debug( "EventSkillTouch" );

	if ( SKILL_CALL:SkillInfo( skillID, SI_CALLTYPE ) & CALL_ENTITY_TOUCH )
	{
		CoreCallValues( .iVictim = iTouched, .iAttacker = iToucher );

		new Int:iSkillNum = EntityGetNum( iToucher, ENTITY_SKILLNUM );
		SkillCall( .skillID = skillID,
					.call = CALL_ENTITY_TOUCH,
					.iPlayer = iOwner,
					.skillNum = iSkillNum,
					.addDelayTime = true
				);

		CoreCallRestoreValues();
	}

	//Reset properties because they may have changed during the SkillCall
	iProp = SKILLENT_PROP:EntityGetNum( iToucher, ENTITY_PROPERTIES );

	if ( iProp & SEP_DAMAGE )
	{
		new Int:iDamage = EntityGetNum( iToucher, ENTITY_DAMAGE );
		if ( iDamage )
		{
			g_iSkillID = skillID;
			SkillDamage( .victim = iTouched, .attacker = iOwner, .damage = iDamage );
			g_iSkillID = SKILL_INVALID;
		}
		if ( iProp & SEP_KILL )
		{
			EntitySoundStop( iToucher );
			EntityKill( iToucher );
		}
	}
	if ( iProp & SEP_AOEDAMAGE )
	{
		new Int:iDamage = EntityGetNum( iToucher, ENTITY_DAMAGE );
		new Float:fRadius = EntityGetFloat( iToucher, ENTITY_RADIUS );
		if ( iDamage && fRadius > 0.0 )
		{
			new Vector:vOrigin[3];
			EntityGetOrigin( iToucher, vOrigin );
			new AOE_FLAGS:iAOEType = AOE_FLAGS:EntityGetNum( iToucher, ENTITY_AOETYPE );

			g_iSkillID = skillID;
			SkillAoEDamage( .attacker = iOwner, .cOrigin = VectorToCoord( vOrigin ), .fRadius = fRadius, .iMaxDamage = iDamage, .flags = iAOEType );
			g_iSkillID = SKILL_INVALID;
		}
		if ( iProp & SEP_KILL )
		{
			EntitySoundStop( iToucher );
			EntityKill( iToucher );
		}
	}

	new POKE_SPRITES:iSprite = POKE_SPRITES:EntityGetNum( iToucher, ENTITY_SPRITE );
	if ( iSprite > SPRITE_NONE )
	{
		new Vector:vOrigin[3];
		EntityGetOrigin( iToucher, vOrigin );

		new Float:fScale = EntityGetFloat( iToucher, ENTITY_SCALE );
		if ( fScale <= 0.0 )
			fScale = 1.0;

		EffectSprite( .cOrigin = VectorToCoord( vOrigin ),
						.iSprite = iSprite,
						.fScale = fScale,
						.iBrightness = 200
					);
	}

	new POKE_SOUNDS:iSound = POKE_SOUNDS:EntityGetNum( iToucher, ENTITY_SOUND );
	if ( iSound > SOUND_NONE )
	{
		EntitySoundEmit( iToucher, iSound );
	}

	pokemod_funcend_debug( "EventSkillTouch" );
}

PM_FUNC_PUBLIC_ATTRIB EventSkillThink( Int:iEntity )
{
	if ( !EntityValid( iEntity ) )
		return;

	if ( g_iState == PM_DISABLED )
	{
		EntitySoundStop( iEntity );
		EntityKill( iEntity );
		return;
	}

	new SKILLENT_PROP:iProp = SKILLENT_PROP:EntityGetNum( iEntity, ENTITY_PROPERTIES );
	if ( !( iProp & SEP_THINK ) )
		return;

	pokemod_funcstart_debug( "EventSkillThink" );

	new Float:fGameTime = get_gametime();

	if ( iProp & SEP_KILL )
	{
		new Float:fKillTime = EntityGetFloat( iEntity, ENTITY_KILLTIME );
		if ( fGameTime >= fKillTime && fKillTime )
		{
			EntitySoundStop( iEntity );
			EntityKill( iEntity );

			pokemod_funcend_debug( "EventSkillThink Entity Killed" );

			return;
		}
	}

	new Int:iOwner = EntityGetNum( iEntity, ENTITY_OWNER );
	if ( !is_user_connected( iOwner ) )
	{
		EntitySoundStop( iEntity );
		EntityKill( iEntity );
		pokemod_funcend_debug( "EventSkillThink Invalid Owner" );
		return;
	}

	new POKESKILL:skillID = POKESKILL:EntityGetNum( iEntity, ENTITY_SKILL );
	new Int:iSkillNum = EntityGetNum( iEntity, ENTITY_SKILLNUM );

	if ( SKILL_CALL:SkillInfo( skillID, SI_CALLTYPE ) & CALL_ENTITY_THINK )
	{
		CoreCallValues( .iAttacker = iEntity );

		SkillCall( .skillID = skillID,
					.call = CALL_ENTITY_THINK,
					.iPlayer = iOwner,
					.skillNum = iSkillNum,
					.addDelayTime = true
				);

		CoreCallRestoreValues();
	}

	//Reset properties because they may have changed during the SkillCall
	iProp = SKILLENT_PROP:EntityGetNum( iEntity, ENTITY_PROPERTIES );

	if ( fGameTime >= EntityGetFloat( iEntity, ENTITY_NEXTDAMAGETIME ) )
	{
		if ( iProp & SEP_AOEDAMAGE && !( iProp & SEP_TOUCH ) )
		{
			new Int:iDamage = EntityGetNum( iEntity, ENTITY_DAMAGE );
			new Float:fRadius = EntityGetFloat( iEntity, ENTITY_RADIUS );
			if ( iDamage && fRadius > 0.0 )
			{
				new Vector:vOrigin[3];
				EntityGetOrigin( iEntity, vOrigin );
				new AOE_FLAGS:iAOEType = AOE_FLAGS:EntityGetNum( iEntity, ENTITY_AOETYPE );

				g_iSkillID = skillID;
				SkillAoEDamage( .attacker = iOwner, .cOrigin = VectorToCoord( vOrigin ), .fRadius = fRadius, .iMaxDamage = iDamage, .flags = iAOEType );
				g_iSkillID = SKILL_INVALID;
			}
		}

		EntitySetFloat( iEntity, ENTITY_NEXTDAMAGETIME, fGameTime + EntityGetFloat( iEntity, ENTITY_DAMAGETIME ) );
	}

	if ( iProp & SEP_PLAYERFOLLOW )
	{
		new Vector:vVelocity[3];
		EntityGetVelocity( iEntity, vVelocity );
		entity_follow_target( .iEntity = iOwner, .iTarget = iEntity, .fSpeed = vector_length( vVelocity ) );
	}

	new Float:fThinkTime = EntityGetFloat( iEntity, ENTITY_THINKTIME );
	set_pev( iEntity, pev_nextthink, fGameTime + fThinkTime );

	pokemod_funcend_debug( "EventSkillThink" );
}

PM_FUNC_PUBLIC_ATTRIB EventMenuClose( Int:id, Int:iKey )
{
	if ( g_iState == PM_DISABLED )
		return;

	pokemod_funcstart_debug( "EventMenuClose" );

	MenuClose( id, MENU_NONE );

	pokemod_funcend_debug( "EventMenuClose" );
}

PM_FUNC_PUBLIC_ATTRIB EventHostageUse( Int:iEntity, Int:iCaller, Int:iActivator, Int:iUseType, Float:fValue )
{
	new String:szClassname[ 32 ];
	pev( iEntity, pev_classname, szClassname, charsmax(szClassname) );
	if ( !equal( szClassname, szEntityPokeOak ) )
		return HAM_IGNORED;

	pokemod_funcstart_debug( "EventHostageUse" );

	if ( is_user_alive( iCaller ) && !fValue )
		MenuMain( iCaller, .bForceDisplay = true );

	pokemod_funcend_debug( "EventHostageUse" );

	return HAM_SUPERCEDE;
}




